﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

namespace block_explorer.Shaders
{
    class ShadowMapEffect : WorldShader
    {
        private const string sEffectFilename = "Effects/ShadowMap";
        private const string sWorldParameterName = "World";
        private const string sViewParameterName = "View";
        private const string sProjectionParameterName = "Projection";
        private const string sDirectionalTechniqueName = "Occlusion";
        private const string sPointTechniqueName = "PointOcclusion";
        private const string sSpotTechniqueName = "Occlusion";

        private Effect mEffect;

        private EffectParameter mWorldMatrix;
        private EffectParameter mViewMatrix;
        private EffectParameter mProjectionMatrix;

        public enum ShadowTechnique
        {
            Directional,
            Point,
            Spot
        }

        private ShadowTechnique mCurrentTechnique;
        private EffectTechnique mDirectionalTechnique;
        private EffectTechnique mPointTechnique;
        private EffectTechnique mSpotTechnique;

        public ShadowTechnique Technique
        {
            set
            {
                switch (value)
                {
                    case ShadowTechnique.Directional:
                        mEffect.CurrentTechnique = mDirectionalTechnique;
                        break;
                    case ShadowTechnique.Point:
                        mEffect.CurrentTechnique = mPointTechnique;
                        break;
                    case ShadowTechnique.Spot:
                        mEffect.CurrentTechnique = mSpotTechnique;
                        break;
                }
                mCurrentTechnique = value;
            }
        }

        public override Matrix World { set { mWorldMatrix.SetValue(value); } }
        public override Matrix View { set { mViewMatrix.SetValue(value); } }
        public override Matrix Projection { set { mProjectionMatrix.SetValue(value); } }

        public override Texture Texture { set { } }

        public override EffectPassCollection Passes { get { return mEffect.CurrentTechnique.Passes; } }

        public ShadowMapEffect(GraphicsDevice device, ContentManager content)
        {
            mEffect = content.Load<Effect>(sEffectFilename);

            mWorldMatrix = mEffect.Parameters[sWorldParameterName];
            mViewMatrix = mEffect.Parameters[sViewParameterName];
            mProjectionMatrix = mEffect.Parameters[sProjectionParameterName];

            mDirectionalTechnique = mEffect.Techniques[sDirectionalTechniqueName];
            mPointTechnique = mEffect.Techniques[sPointTechniqueName];
            mSpotTechnique = mEffect.Techniques[sSpotTechniqueName];
        }
    }
}
